<template>
  <div class="carousel" @mouseenter="mouseEnter" @mouseleave="mouseLeave">
    <div class="inner">
      <car-dot
        :hasDot="hasDot"
        :itemLength="itemLength"
        :currentIndex="currentIndex"
        :dotBgColor="dotBgColor"
        @dotClick="dotClick"
      ></car-dot>
      <car-director dir="prev" @dirClick="dirClick"></car-director>
      <car-director dir="next" @dirClick="dirClick"></car-director>
      <slot></slot>
    </div>
  </div>
</template>

<script>
import { reactive, toRefs } from "@vue/reactivity";
import {
  getCurrentInstance,
  onBeforeUnmount,
  onMounted,
} from "@vue/runtime-core";
import CarDot from "./Dot.vue";
import CarDirector from "./Director.vue";
export default {
  name: "Carousel",
  components: { CarDot, CarDirector },
  props: {
    autoplay: {
      type: Boolean,
      default: true,
    },
    duration: {
      type: Number,
      default: 3000,
    },
    initial: {
      type: Number,
      default: 0,
    },
    hasDot: {
      type: Boolean,
      default: true,
    },
    hasDirector: {
      type: Boolean,
      default: true,
    },
    dotBgColor: {
      type: String,
    },
  },
  setup(props) {
    const instance = getCurrentInstance();
    const state = reactive({
      currentIndex: props.initial,
      itemLength: 0,
    });
    let t = null;
    const autoPlay = () => {
      if (props.autoplay) {
        t = setInterval(() => {
          setIndex("prev");
        }, props.duration);
      }
    };
    const setIndex = (dir) => {
      switch (dir) {
        case "next":
          state.currentIndex += 1;
          if (state.currentIndex === state.itemLength) {
            state.currentIndex = 0;
          }
          break;

        case "prev":
          state.currentIndex -= 1;
          if (state.currentIndex === -1) {
            state.currentIndex = state.itemLength - 1;
          }
          break;
        default:
          break;
      }
    };
    onMounted(() => {
      const arr = instance.slots.default();
      if (arr[0].children.length) {
        state.itemLength = arr[0].children.length;
      } else state.itemLength = arr.length;
      autoPlay();
    });
    onBeforeUnmount(() => {
      clearInterval(t);
      t = null;
    });
    const dotClick = (index) => {
      state.currentIndex = index;
    };
    const mouseEnter = () => {
      clearInterval(t);
      t = null;
    };
    const mouseLeave = () => {
      autoPlay();
    };
    const dirClick = (dir) => {
      setIndex(dir);
    };
    return {
      ...toRefs(state),
      dotClick,
      mouseEnter,
      mouseLeave,
      dirClick,
    };
  },
};
</script>

<style scoped>
.carousel {
  width: 100%;
  height: 100%;
}
.carousel .inner {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
}
</style>